package com.xunji.user.common;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.interfaces.DecodedJWT;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * token制作工具类
 *
 * @Author qiangxu9
 * @Date 2021年07月15日 星期四
 * @Version 1.0
 * @Description trial-service
 */
public class Token {

    //设置过期时间
    // private static final long EXPIRE_DATE = 2 * 60 * 60 * 1000; // 超期时间俩小时
    //token秘钥
    private static final String TOKEN_SECRET = "r54eg5sae4r665ser54rg";

    private static Token token = new Token();

    private Token() {
    }

    public static Token getInstance() {
        return token;
    }

    /**
     * 实现签名方法
     *
     * @param username   加密字段,如userName
     * @param expireDate 过期时间(单位:秒)
     * @return token
     */
    public String getToken(String username, long expireDate) {
        String token = "";
        try {
            //这里将useName存入了Token，在下面的解析中，也会有解析的方法可以获取到Token里面的数据
            //Token过期的时间
            //过期时间
            Date date = new Date(System.currentTimeMillis() + expireDate * 1000);
            //秘钥及加密算法
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            //设置头部信息,类型以及签名所用的算法
            Map<String, Object> header = new HashMap<>();
            header.put("typ", "JWT");
            header.put("alg", "HS256");
            //携带username，password信息，存入token，生成签名
            token = JWT.create()
                    .withHeader(header)
                    //存储自己想要留给前端的内容
                    .withClaim("loginName", username)
                    .withExpiresAt(date)
                    .sign(algorithm);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
        return token;
    }

    //验证token
    public boolean verify(String token) {
        /**
         * @desc 验证token，通过返回true
         * @params [token]需要校验的串
         **/
        try {
            Algorithm algorithm = Algorithm.HMAC256(TOKEN_SECRET);
            JWTVerifier verifier = JWT.require(algorithm).build();
            DecodedJWT jwt = verifier.verify(token); // 不必在乎返回结果,校验通过会返回true,不通过直接抛异常,返回false
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;

    }

    /**
     * 获取token中信息 loginName
     *
     * @param token
     * @return true or false
     */
    public String getUsername(String token) {
        try {
            if (token == null) {
                return null;
            }
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("loginName").asString();
        } catch (JWTDecodeException e) {
            e.printStackTrace();
        }
        return null;
    }
}
